
#include "cansocket.hpp"

#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <stdexcept>
#include <unistd.h>
#include <errno.h>
#include <iostream>      // std::cout  
#include <thread>    // std::thread 
#include <cstring>
//#include <algorithm>

#include <boost/static_assert.hpp>
using namespace boost::asio;
CanSocket::CanSocket(const char *canNo)
{
  
  open_id = socket(PF_CAN, SOCK_RAW, CAN_RAW); // 创建套接字
  strcpy(ifr.ifr_name, canNo);
  ioctl(open_id, SIOCGIFINDEX, &ifr); // 指定设备
  addr.can_family = AF_CAN;
  addr.can_ifindex = ifr.ifr_ifindex;
  bind(open_id, (struct sockaddr *)&addr, sizeof(addr)); // 将套接字与 can0 绑定
  read_can_flag=0;
  rec_id.rec_id_count=0;
  for(int i=0;i<4;i++)
    rec_id.lun_speed_set[i]=0;
  rec_id.rec_id[0]=0x211;
  rec_id.rec_id[1]=0x212;  
}
CanSocket::~CanSocket()
{
}
void CanSocket::write_can(unsigned char *sd, u_int16_t id)
{
  int nb;
  can_send_fram[0].can_id = id;
  can_send_fram[0].can_dlc = 8;
  for (int i = 0; i < 8; i++)
    can_send_fram[0].data[i] = sd[i];
  nb = write(open_id, &can_send_fram[0], sizeof(can_send_fram[0])); // 发送 frame[0]
  /*
  if (nb != sizeof(can_send_fram[0]))
  {
    printf("Send Error frame[0]\n!");
  }*/
}
void CanSocket::run()
{
  int i;
  // usleep(1000);
  // thread_ret = pthread_create( &my_thread, NULL, &CanSocket::read_can, (void *)this);
   // run_thread_ = std::thread(&CanSocket::runThreadFunc, this);
   // run_thread_.detach();
    read_thread_ = std::thread(&CanSocket::read_can, this);
    read_thread_.detach();
    send_thread_ = std::thread(&CanSocket::write_lun, this);
    send_thread_.detach();
   
}
void CanSocket::write_lun(void)
{
  int i,nv;
  static unsigned char ccstr[8];
  while(1)
  {
    for(i=0;i<2;i++)
    {
      nv=1;
     if(i==0)nv=1;
     if(i==1)nv=-1; 
     usleep(3000); 
    ccstr[0]=(rec_id.lun_speed_set[i]*nv)>>8;  
    ccstr[1]=(rec_id.lun_speed_set[i]*nv)&0xff;  
    write_can(ccstr,(rec_id.rec_id[i]-0x10));
   // printf("lun%d=%d ",i,rec_id.lun_speed_set[i]);
    }
  }
}
void * CanSocket::read_can()
{
  int i;
   while(1)
   {
    
   // read_can_flag=0;
   if(read_can_flag==0)
   {can_rec_fram[0].can_dlc=0;
   int nbytes = read(open_id, &can_rec_fram[0], sizeof(can_rec_fram[0]));
   if(nbytes!=sizeof(can_rec_fram[0]))
        printf("rec err= %x\n",nbytes);
   for(i=0;i<rec_id.rec_id_count;i++)
     {
      if(can_rec_fram[0].can_id==rec_id.rec_id[i])read_can_flag=1;
     }     
    }
   }
    return NULL;
}
int CanSocket::get_rec_flag()
{
  return read_can_flag;
}
u_char * CanSocket::get_rec_str()
{ 
  static u_char rt[8];
  int i;
  read_can_flag=0;
  for(i=0;i<8;i++)rt[i]=can_rec_fram[0].data[i];
  return rt;
}
void CanSocket::add_can_filter(u_int16_t id)
{
 if(rec_id.rec_id_count>7)return;
 rec_id.rec_id[rec_id.rec_id_count]=id;
 rec_id.rec_id_count++;
}
void CanSocket::runThreadFunc()
{
    // startAsyncRead();
    
}
void CanSocket::set_lun_speed(int16_t sp,int index)
{
  rec_id.lun_speed_set[index]=sp;
}


